package cn.teduymdj.jxc.service.impl;

import cn.teduymdj.jxc.mapper.*;
import cn.teduymdj.jxc.pojo.dto.GoodsAddNewDTO;
import cn.teduymdj.jxc.pojo.dto.GoodsUpdateInfoDTO;
import cn.teduymdj.jxc.pojo.entity.Goods;
import cn.teduymdj.jxc.pojo.vo.GoodsInventoryListItemVO;
import cn.teduymdj.jxc.pojo.vo.GoodsListItemVO;
import cn.teduymdj.jxc.pojo.vo.GoodsStandardVO;
import cn.teduymdj.jxc.repo.GoodsRedisRepository;
import cn.teduymdj.jxc.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * 处理货物表相关业务的实现类
 *
 * @author 陈坤鹏
 */
@Slf4j
@Service
public class GoodsServiceImpl implements GoodsService {

    public GoodsServiceImpl() {
        log.debug("创建业务对象:GoodsServiceImpl");
    }

    @Autowired
    GoodsRedisRepository goodsRedisRepository;
    @Autowired
    GoodsMapper goodsMapper;
    @Autowired
    SaleListGoodsMapper saleListGoodsMapper;
    @Autowired
    CustomerReturnListGoodsMapper customerReturnListGoodsMapper;


    /**
     * 根据商品类别ID查询商品
     *
     * @param typeId 商品类别ID
     * @return 查询出的数据
     */
    @Override
    public List<GoodsStandardVO> getGoodsByTypeId(Long typeId) {
        List<GoodsStandardVO> goodsByTypeId = goodsMapper.getGoodsByTypeId(typeId);
        log.debug("查询出的数据:{}", goodsByTypeId);
        return goodsByTypeId;
    }

    @Override
    public List<GoodsListItemVO> getGoodsList(Integer page, Integer pageSize, String name, Long typeId) {
        log.debug("页数:{},每页数据量:{}",page,pageSize);
        return goodsMapper.list();
    }

    /**
     * 查询商品记录数
     *
     * @param name   商品名称
     * @param typeId 商品类别ID
     * @return 查询出的数据条数
     */
    @Override
    public Long getGoodsCount(String name, Long typeId) {
        Long goodsCount = goodsMapper.getGoodsCount(name, typeId);
        log.debug("查询出【{}】条数据", goodsCount);
        return goodsCount;
    }

    /**
     * 查询当前商品最大的编码号
     *
     * @return 查询出的结果
     */
    @Override
    public String getMaxCode() {
        String maxCode = goodsMapper.getMaxCode();
        log.debug("查询结果:{}", maxCode);
        return maxCode;
    }

    /**
     * 新增商品信息
     *
     * @param goodsAddNewDTO 商品实体
     */
    @Override
    public void saveGoods(GoodsAddNewDTO goodsAddNewDTO) {
        int row = goodsMapper.addNew(goodsAddNewDTO);
        log.debug("新增商品完成，影响行数:{}", row);
    }

    /**
     * 修改商品信息
     *
     * @param goodsUpdateInfoDTO 商品实体
     */
    @Override
    public void updateGoods(GoodsUpdateInfoDTO goodsUpdateInfoDTO) {
        int row = goodsMapper.update(goodsUpdateInfoDTO);
        log.debug("修改商品完成，影响行数:{}", row);
    }

    /**
     * 删除商品信息
     *
     * @param id 商品ID
     */
    @Override
    public void deleteGoodsById(Long id) {
        int row = goodsMapper.deleteById(id);
        log.debug("根据id删除商品完成，影响行数:{}", row);
    }

    /**
     * 根据商品ID查询商品
     *
     * @param id 商品ID
     * @return 商品实体
     */
    @Override
    public GoodsStandardVO findByGoodsId(Long id) {
        GoodsStandardVO goodsStandardVO = goodsMapper.findByGoodsId(id);
        log.debug("根据商品id查询商品的结果为:{}", goodsStandardVO);
        return goodsStandardVO;
    }

    @Override
    public List<GoodsListItemVO> getNoInventoryQuantity(Integer page, Integer pageSize, String nameOrCode) {
        return goodsMapper.listNoInventory();
    }

    /**
     * 查询没有库存的商品数量
     * @param nameOrCode  搜索条件，商品名称或商品编码
     * @return 商品数量
     */
    @Override
    public Long getNoInventoryQuantityCount(String nameOrCode) {
        return goodsMapper.getNoInventoryQuantityCount(nameOrCode);
    }


    @Override
    public List<GoodsListItemVO> getHasInventoryQuantity(Integer page, Integer pageSize, String nameOrCode) {
        return goodsMapper.listHasInventory();
    }

    /**
     * 查询有库存的商品数量
     * @param nameOrCode  搜索条件，商品名称或商品编码
     * @return 商品数量
     */
    @Override
    public Long getHasInventoryQuantityCount(String nameOrCode) {
        return goodsMapper.getHasInventoryQuantityCount(nameOrCode);
    }

    /**
     * 查询商品库存信息记录数
     *
     * @param codeOrName 商品编码或名称
     * @param typeId     商品类别ID
     * @return
     */
    @Override
    public Long getGoodsInventoryCount(String codeOrName, Long typeId) {
        return goodsMapper.getGoodsInventoryCount(codeOrName, typeId);
    }

    @Override
    public List<GoodsInventoryListItemVO> getGoodsInventoryList(
            Integer page, Integer pageSize, String codeOrName, Long typeId) {
        List<GoodsInventoryListItemVO> list = goodsMapper.listInventory();
        for (GoodsInventoryListItemVO item : list) {
            item.setInventoryPrice(item.getSellingPrice()
                    .multiply(new BigDecimal(
                            Integer.parseInt (
                                    item.getInventoryQuantity().toString() ) )));
            Integer count = saleListGoodsMapper.getCountByGoodsId(item.getId());
            Integer count1 = customerReturnListGoodsMapper.getCountByGoodsId(item.getId());
            item.setSaleTotal(count-count1);
        }
        return list;
    }

    @Override
    public List<GoodsListItemVO> getGoodsAlarm() {
        return goodsMapper.getGoodsAlarm();
    }

    @Override
    public void rebuildCache() {
        log.debug("开始处理【重建商品缓存】的业务，无参数");
        log.debug("准备删除Redis缓存中的商品数据……");
        goodsRedisRepository.deleteAll();
        log.debug("删除Redis缓存中的商品数据，完成！");

        log.debug("准备从数据库中读取商品列表……");
        List<GoodsListItemVO> list = goodsMapper.list();
        log.debug("从数据库中读取商品列表，完成！");

        log.debug("准备将商品列表写入到Redis缓存……");
        goodsRedisRepository.save(list);
        log.debug("将商品列表写入到Redis缓存，完成！");

        log.debug("准备将各商品详情写入到Redis缓存……");
        for (GoodsListItemVO brandListItemVO : list) {
            Long id = brandListItemVO.getId();
            GoodsStandardVO standardById = goodsMapper.getStandardById(id);
            goodsRedisRepository.save(standardById);
        }
        log.debug("将各商品详情写入到Redis缓存，完成！");
    }
}
